home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / RAVE SDK 1.5 MacOS / RaveDemo / MyShape.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  5.2 KB  |  231 lines  |  [TEXT/CWIE]

  1. #include "MyHeader.h"
  2.  
  3.  
  4.  
  5.  
  6. MyShape * MyShapeNew(void)
  7. {
  8.     return calloc(sizeof (MyShape), 1);
  9. }
  10.  
  11. void MyShapeDispose(MyShape * shape)
  12. {
  13.     if(shape){
  14.         free(shape->pointList);
  15.         free(shape->triangleList);
  16.     }
  17.     free(shape);
  18. }
  19.  
  20. MyShape * MyShapeLoad(char * fileName)
  21. {
  22.     FILE * f;
  23.     MyShape * shape = NULL;
  24.     
  25.     char s[1000];
  26.     long x;
  27.     MyVector * p;
  28.     MyTri * t;
  29.     float len;
  30.     
  31.     /********/
  32.  
  33.     f = fopen(fileName, "r");
  34.     if(!f) goto fail1;
  35.     
  36.     shape = MyShapeNew();
  37.     
  38.     fgets(s, sizeof s, f);
  39.     sscanf(s, "%ld", &shape->pointCount);
  40.     shape->pointList = malloc(sizeof (MyVector) * shape->pointCount);
  41.     for(x = 0; x < shape->pointCount; x++){
  42.         p = &shape->pointList[x];
  43.         fgets(s, sizeof s, f);
  44.         sscanf(s, "%f,%f,%f", &p->x, &p->y, &p->z);
  45.         
  46.         len = MyVectorLength(p);
  47.         if(len > shape->maxDimention) shape->maxDimention = len;
  48.     }
  49.     
  50.     fgets(s, sizeof s, f);
  51.     sscanf(s, "%ld", &shape->triangleCount);
  52.     shape->triangleList = malloc(sizeof (MyTri) * shape->triangleCount);
  53.     for(x = 0; x < shape->triangleCount; x++){
  54.         t = &shape->triangleList[x];
  55.         fgets(s, sizeof s, f);
  56.         sscanf(s, "%ld,%f,%f,%ld,%f,%f,%ld,%f,%f,%hd", 
  57.             &t->corner[0].pointNumber, &t->corner[0].u, &t->corner[0].v, 
  58.             &t->corner[1].pointNumber, &t->corner[1].u, &t->corner[1].v, 
  59.             &t->corner[2].pointNumber, &t->corner[2].u, &t->corner[2].v,
  60.             &t->texture);             
  61.     }
  62.     
  63.     
  64.     fclose(f);
  65. fail1:
  66.     return shape;
  67. }
  68.  
  69. #define margin 0.001
  70.  
  71. static long AddToNormalList(long * countVar, MyVector * normalList, MyVector * newNormal)
  72. {
  73.     long x;
  74.     
  75.     for(x = 0; x < *countVar; x++){
  76.         if(MyVectorDistance(newNormal, &normalList[x]) < margin) return x;
  77.     }
  78.     
  79.     x = *countVar;
  80.     
  81.     normalList[x] = *newNormal;
  82.     
  83.     (*countVar)++;
  84.     
  85.     return x;
  86. }
  87.  
  88. static void CalcTriNormal(const MyShape * shape, long theTri, MyVector * normal)
  89. {
  90.     MyTri * tri;
  91.     MyVector * points;
  92.     MyVector v1, v2;
  93.     /********/
  94.  
  95.     points = shape->pointList;
  96.     tri = &shape->triangleList[theTri];
  97.     MyVectorSubtract(&points[tri->corner[1].pointNumber], &points[tri->corner[0].pointNumber], &v1);
  98.     MyVectorSubtract(&points[tri->corner[2].pointNumber], &points[tri->corner[0].pointNumber], &v2);
  99.     MyVectorCrossProduct(&v2, &v1, normal);
  100.     MyVectorNormalize(normal, normal);
  101.  
  102. }
  103.  
  104. void MyShapeCalculateNormals(MyShape * shape, short mode)
  105. {
  106.     long x, y, c, pn;
  107.     MyVector * points;
  108.     long * normalTable;        // the number of entries is  triangleCount for flat shading or triangleCount * 3 for per vertex shading
  109.     long normalCount;
  110.     long normalCount2;
  111.     MyVector * normalList;
  112.     MyVector * normalList2;
  113.     MyVector n, n2, n3;
  114.     MyTri * tri;
  115.     float vectorDistance;
  116.     
  117.     /*****/
  118.     
  119.     
  120.  
  121.     points = shape->pointList;
  122.     normalCount = 0;
  123.  
  124.     switch(mode){
  125.     case 0:
  126.         // per vertex - only for spheres
  127.         MYCALLOC(normalTable, shape->triangleCount * 3);
  128.         MYCALLOC(normalList, shape->triangleCount * 3);
  129.         
  130.         for(x = 0; x < shape->triangleCount; x++){
  131.             tri = &shape->triangleList[x];
  132.             for(c = 0; c < 3; c++){
  133.                 MyVectorNormalize(&points[tri->corner[c].pointNumber], &n);
  134.                 normalTable[x * 3 + c] = AddToNormalList(&normalCount, normalList, &n);
  135.             }                
  136.         }
  137.         break;
  138.     case 1:
  139.         // flat shading
  140.         MYCALLOC(normalTable, shape->triangleCount);
  141.         MYCALLOC(normalList, shape->triangleCount);
  142.         
  143.         for(x = 0; x < shape->triangleCount; x++){
  144.             CalcTriNormal(shape, x, &n);
  145.             normalTable[x] = AddToNormalList(&normalCount, normalList, &n);
  146.         }
  147.         break;
  148.     case 2:
  149.         // per vertex - auto smooth
  150.         MYCALLOC(normalTable, shape->triangleCount * 3);
  151.         MYCALLOC(normalList, shape->triangleCount * 3);
  152.         MYCALLOC(normalList2, shape->triangleCount);
  153.         for(x = 0; x < shape->triangleCount; x++){
  154.             CalcTriNormal(shape, x, &n);
  155.             tri = &shape->triangleList[x];
  156.             
  157.             for(c = 0; c < 3; c++){
  158.                 normalList2[0] = n;
  159.                 normalCount2 = 1;
  160.                 pn = tri->corner[c].pointNumber;
  161.                 
  162.                 for(y = 0; y < shape->triangleCount; y++){
  163.                     if(shape->triangleList[y].corner[0].pointNumber == pn ||
  164.                         shape->triangleList[y].corner[1].pointNumber == pn ||
  165.                         shape->triangleList[y].corner[2].pointNumber == pn){
  166.                         
  167.                         CalcTriNormal(shape, y, &n2);
  168.                         vectorDistance = MyVectorDistance(&n, &n2);
  169.                         if(vectorDistance < 1.0){
  170.                             AddToNormalList(&normalCount2, normalList2, &n2);
  171.                         }
  172.                         
  173.                     }
  174.                 }
  175.                 n3.x = n3.y = n3.z = 0;
  176.                 for(y = 0; y < normalCount2; y++){
  177.                     MyVectorAdd(&normalList2[y], &n3, &n3);
  178.                 }
  179.                 MyVectorNormalize(&n3, &n3);
  180.                 normalTable[x * 3 + c] = AddToNormalList(&normalCount, normalList, &n3);
  181.             }
  182.         }
  183.         mode = 0; // for setting shape->normalMode
  184.         MYFREE(normalList2);
  185.         break;
  186.     }    
  187.     MYREALLOC(normalList, normalCount);
  188.  
  189.     shape->normalTable = normalTable;
  190.     shape->normalList = normalList;
  191.     shape->normalCount = normalCount;
  192.     shape->normalMode = mode;
  193. }
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. void MyShapeSave(MyShape * shape, char * fileName)
  201. {
  202.     long x;
  203.     MyVector * p;
  204.     MyTri * t;
  205.     FILE * f;
  206.  
  207.     f = fopen(fileName, "w");
  208.     fprintf(f, "%ld\n", shape->pointCount);
  209.  
  210.     for(x = 0; x < shape->pointCount; x++){
  211.         p = &shape->pointList[x];
  212.         fprintf(f, "%f,%f,%f\n", p->x, p->y, p->z);
  213.     }
  214.     
  215.     fprintf(f, "%ld\n", shape->triangleCount);
  216.  
  217.     for(x = 0; x < shape->triangleCount; x++){
  218.         t = &shape->triangleList[x];
  219.         fprintf(f, "%ld,%f,%f,%ld,%f,%f,%ld,%f,%f,%hd\n", 
  220.             t->corner[0].pointNumber, t->corner[0].u, t->corner[0].v, 
  221.             t->corner[1].pointNumber, t->corner[1].u, t->corner[1].v, 
  222.             t->corner[2].pointNumber, t->corner[2].u, t->corner[2].v,
  223.             t->texture);             
  224.     }
  225.     
  226.     
  227.     fclose(f);
  228.  
  229.  
  230. }
  231.